// 强制启用unicode
#define UNICODE
#include <windows.h>
#include <stdio.h>
#include <string.h>

// 定义一个结构体存储串口信息
typedef struct _SERIAL_INFO {
    DWORD dwSize;
    HANDLE hFile;
    DWORD dwDeviceType;
    DWORD dwReserved;
    DWORD dwProviderSubType;
    DWORD dwServiceCharacteristics;
    DWORD dwVendorGuidData;
    DWORD dwDriverVersion;
    DWORD dwDriverDate;
    DWORD dwHardwareIndex;
    DWORD dwConfigFlags;
    DWORD dwNumParameters;
    DWORD dwNumProperties;
} SERIAL_INFO;

// 定义一个结构体存储串口属性
typedef struct _SERIAL_PROPERTY_KEY {
    DWORD dwPropertyKey;
    DWORD dwPropertyType;
    DWORD dwReserved;
} SERIAL_PROPERTY_KEY;

int main() {
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;
    HANDLE hComm = NULL;
    SERIAL_INFO SerialInfo;
    SERIAL_PROPERTY_KEY SerialPropKey;
    TCHAR szPortName[MAX_PATH];
    DWORD dwBufferSize = 0;
    DWORD dwBytesReturned = 0;
    DWORD dwError = 0;

    // 获取所需的SERIAL_INFO结构体大小
    dwRetVal = QueryDosDevice(NULL, NULL, 0);
    if (dwRetVal == 0) {
        dwSize = GetLastError();
        SerialInfo.dwSize = dwSize;
    } else {
        printf("QueryDosDevice failed with error: %ld\n", GetLastError());
        return -1;
    }

    // 枚举所有的串口
    for (int i = 1; i <= 256; i++) {
        wsprintf(szPortName, TEXT("COM%d"), i);
        dwRetVal = QueryDosDevice(szPortName, NULL, 0);
        if (dwRetVal != 0) {
            continue; // 如果返回非零，则跳过，表示端口不存在或不可用
        }
        dwError = GetLastError();
        if (dwError != ERROR_INSUFFICIENT_BUFFER) {
            continue; // 如果错误不是缓冲区不足，则跳过
        }

        // 如果是缓冲区不足，则获取正确的缓冲区大小
        dwBufferSize = dwError;
        if (dwBufferSize > 0) {
            SerialInfo.dwSize = dwBufferSize;
            dwRetVal = QueryDosDevice(szPortName, (LPTSTR)&SerialInfo, dwBufferSize);
            if (dwRetVal != 0) {
                // 成功获取串口信息，尝试打开串口
                hComm = CreateFile(szPortName,
                                   GENERIC_READ | GENERIC_WRITE,
                                   0, NULL,
                                   OPEN_EXISTING,
                                   FILE_ATTRIBUTE_NORMAL,
                                   NULL);
                if (hComm != INVALID_HANDLE_VALUE) {
                    // 打印可用的串口号
                    wprintf(L"Found COM port: %s\n", szPortName);
                    // 清理资源
                    CloseHandle(hComm);
                }
            }
        }
    }

    return 0;
}
